package cn.com.utils;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

@Slf4j
public class LoopSpeedTest {
    public static long testForLoop(List<Integer> list) {
        long startTime = System.nanoTime();
        for (int i = 0; i < list.size(); i++) {
            int result = i + 1; // 执行一些操作
        }
        return System.nanoTime() - startTime;
    }

    public static long testEnhancedForLoop(List<Integer> list) {
        long startTime = System.nanoTime();
        for (int num : list) {
            int result = num + 1; // 执行一些操作
        }
        return System.nanoTime() - startTime;
    }

    public static long testWhileLoop(List<Integer> list) {
        int i = 0;
        long startTime = System.nanoTime();
        while (i < list.size()) {
            int result = i + 1; // 执行一些操作
            i++;
        }
        return System.nanoTime() - startTime;
    }

    public static long testStreamLoop(List<Integer> list) {
        Stream<Integer> stream = list.stream();
        long startTime = System.nanoTime();
        stream.forEach(num -> {
            int result = num + 1; // 执行一些操作
        });
        return System.nanoTime() - startTime;
    }

    public static long testForLoopSum(List<Integer> list) {
        long sum = 0;
        int size = list.size();
        long startTime = System.nanoTime();
        for (int i = 0, num = 0; i < size; num = list.get(i++)) {
            if (num % 2 == 0) {
                int squared = num * num;
                if (squared > 100) {
                    sum += squared;
                }
            }
        }

        return System.nanoTime() - startTime;
    }

    public static long testStreamLoopSum(List<Integer> list) {
        long startTime = System.nanoTime();
        long sum = list.stream()
                .filter(num -> num % 2 == 0)
                .mapToInt(i -> i * i)
                .filter(squared -> squared > 100)
                .sum();
        return System.nanoTime() - startTime;
    }

    @Test
    public void main2() {
        int n = 10000 * 10000;
        List<Integer> stream = IntStream.range(0, n).boxed().collect(Collectors.toList());
        long forLoopTime = testForLoopSum(stream);
        long streamLoopTime = testStreamLoopSum(stream);
        //long forLoopTime = testForLoop(stream);
        //long streamLoopTime = testStreamLoop(stream);

        System.out.println("普通for循环时间: " + forLoopTime + " 纳秒" + " 约等于 " + forLoopTime / 1000000 + " 毫秒" + " 约等于 " + forLoopTime / 1000 + " 微秒" + " 约等于 " + forLoopTime / 1000000000 + " 秒");
        System.out.println("Stream循环时间: " + streamLoopTime + " 纳秒" + " 约等于 " + streamLoopTime / 1000000 + " 毫秒" + " 约等于 " + streamLoopTime / 1000 + " 微秒" + " 约等于 " + streamLoopTime / 1000000000 + " 秒");

        //相差
        System.out.println("相差: " + (forLoopTime - streamLoopTime) / 1000000 + " 毫秒");
        //倍数
        System.out.println("倍数: " + (forLoopTime / streamLoopTime) + " 倍");

        if (forLoopTime < streamLoopTime) {
            System.out.println("普通for循环更快！");
        } else {
            System.out.println("Stream循环更快！");
        }
    }

    @Test
    public void main1() {
        int n = 10000000;
        List<Integer> stream = IntStream.range(0, n).boxed().collect(Collectors.toList());
        long forLoopTime = testForLoop(stream);
        long enhancedForLoopTime = testEnhancedForLoop(stream);
        long whileLoopTime = testWhileLoop(stream);
        long streamLoopTime = testStreamLoop(stream);

        System.out.println("普通for循环时间: " + forLoopTime + " 纳秒");
        System.out.println("增强型for循环时间: " + enhancedForLoopTime + " 纳秒");
        System.out.println("while循环时间: " + whileLoopTime + " 纳秒");
        System.out.println("Stream循环时间: " + streamLoopTime + " 纳秒");

        if (forLoopTime < enhancedForLoopTime && forLoopTime < whileLoopTime && forLoopTime < streamLoopTime) {
            System.out.println("普通for循环更快！");
        } else if (enhancedForLoopTime < forLoopTime && enhancedForLoopTime < whileLoopTime && enhancedForLoopTime < streamLoopTime) {
            System.out.println("增强型for循环更快！");
        } else if (whileLoopTime < forLoopTime && whileLoopTime < enhancedForLoopTime && whileLoopTime < streamLoopTime) {
            System.out.println("while循环更快！");
        } else {
            System.out.println("Stream循环更快！");
        }
    }
}
